#include "rc_control.h"
#include "socketx.h"

typedef struct {
    int sock;
} rc_global;

int  rc_init()
{
    socketx_init();
    
    return 0;
}

int  rc_unit()
{
    socketx_unit();
    
    return 0;
}

int  rc_open_device(const char *addr, short port, const char *password, long* rc_handle)
{
    rc_global* rc = (rc_global*)malloc(sizeof(rc_global));
    if (rc == 0)
    {
        return -1;
    }
    memset(rc, 0, sizeof(rc_global));
    *rc_handle = (long)rc;
    
    rc->sock = socketx_create(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (rc->sock < 0)
    {
        return -1;
    }
    
    struct sockaddr_in remoteAddr;
    remoteAddr.sin_family = AF_INET;
    remoteAddr.sin_port = htons(3636);
    remoteAddr.sin_addr.s_addr = inet_addr(addr);
    if (socketx_connect(rc->sock, (struct sockaddr *)&remoteAddr, sizeof(remoteAddr), 3000) < 0)
    {
        return -2;
    }
    
    rc_commond_pack_t pack = {0};
    pack.head.major = RC_MAJOR_CMD_LOGINDEVICE;
    pack.head.minor = 0;
    pack.head.bytes = sizeof(rc_loginparam_t);
    
    rc_loginparam_t* info = (rc_loginparam_t*)pack.body;
    strcpy(info->password, password);
    
    if (sizeof(rc_commond_head_t) != socketx_send(rc->sock, &(pack.head), sizeof(rc_commond_head_t), 0))
    {
        return -3;
    }
    
    if (pack.head.bytes != socketx_send(rc->sock, &(pack.body), pack.head.bytes, 0))
    {
        return -3;
    }
    
    
    memset(&pack, 0, sizeof(pack));
    
    if (sizeof(rc_commond_head_t) != socketx_recv(rc->sock, &(pack.head), sizeof(rc_commond_head_t), 0))
    {
        return -3;
    }
    
    if (pack.head.bytes != socketx_recv(rc->sock, &(pack.body), pack.head.bytes, 0))
    {
        return -3;
    }
    
    if (pack.head.error != RC_ERROR_SUCCESS)
    {
        return -4;
    }
    
    return 0;
}

int  rc_shut_device(long rc_handle)
{
    rc_global* rc = (rc_global*)rc_handle;
    if (rc == 0)
    {
        return -1;
    }
    
    socketx_close(rc->sock);
    rc->sock = 0;
    
    free(rc);
    
    return 0;
}

int  rc_send_commond(long rc_handle, rc_commond_pack_t *pack)
{
    rc_global* rc = (rc_global*)rc_handle;
    if (rc == 0)
    {
        return -1;
    }
    
    if (sizeof(rc_commond_head_t) != socketx_send(rc->sock, &(pack->head), sizeof(rc_commond_head_t), 0))
    {
        return 0;
    }
    
    if (pack->head.bytes != socketx_send(rc->sock, &(pack->body), pack->head.bytes, 0))
    {
        return 0;
    }
    
    memset(&pack, 0, sizeof(pack));
    
    if (sizeof(rc_commond_head_t) != socketx_recv(rc->sock, &(pack->head), sizeof(rc_commond_head_t), 0))
    {
        return 0;
    }
    
    if (pack->head.bytes != socketx_recv(rc->sock, &(pack->body), pack->head.bytes, 0))
    {
        return 0;
    }
    
    if (pack->head.error != RC_ERROR_SUCCESS)
    {
        return 0;
    }
    
    return 0;
}